# 毕业设计 Makefile
# 王伟 <wangxiaowei0303@163.com>
#
# make 目录如下;
# * all; 编译,生成可执行文件,存放在 bin/ 目录下.
# * run; 先执行 all 目标,然后运行 bin/ 下生成的可执行文件.
# * clean; 删除编译过程中生成的目标文件,以及最终生成的可执行文件
# * dist; 将所有被 git 追踪到的文件打包,压缩.

# 详尽输出.
# 若注释掉 'V=1' 行,则不详尽输出.
V = 1;
ifdef V
MUTE =
VTAG = -v
else
MUTE = @
endif

PACKAGE = bishe
VERSION = $(shell git describe --tags)
DATE    = $(shell date)

# EXE; 可执行文件名.
# 预处理器选项设置;
# INCLUDEDIR; -I 编译选项列表,同时作用在 .c,.cc 文件上.
# DEFINES; 预定义宏.
#   * ENABLE_DEBUG; 当定义该宏时,会编译一些调试代码,大多是一些输出代码.
# 编译选项设置;
# CFLAGS; 编译 .c 文件时使用的编译选项.
# CXXFLAGS; 编译 .cc 文件时使用的编译选项.
#
# 链接器选项设置;
# LDFLAGS; 链接选项..c,.cc 文件在被编译后生成的目标文件放在一起链接.
#          因此只有一个 LDFLAGS,并没有 CLDFLAGS,CXXLDFLAGS.
EXE         = $(PACKAGE)
INCLUDESDIR = 
DEFINES     =          
CFLAGS      = -O2 -Wall
CXXFLAGS    = $(CFLAGS)
LDFLAGS     = -O2

# 项目源文件.
CFILES   = $(shell find src/ -maxdepth 1  -type f -name '*.c')
CXXFILES = $(shell find src/ -maxdepth 1  -type f -name '*.cc')
OBJECTS  = $(CFILES:.c=.c.o) \
           $(CXXFILES:.cc=.cc.o)

# 生成代码压缩包时相关设置;
# TARNAME; 代码压缩包名,不带后缀.
# DISTDIR; 临时文件夹名.
# 逻辑:
# 1. 首先创建一个临时文件夹,然后将 git 追踪到的所有文件复制到该文件夹中,
# 2. 使用 tar 命令将该文件夹打包.
TARNAME = $(PACKAGE)-$(VERSION)
DISTDIR = $(TARNAME)

# 因为 NoiseAlgorithm 会被之后的加噪,去噪算法使用.所以将其编译,链接成一个单独的
# so 文件.
NOISEALGO_CXXFILES = $(shell find src/NoiseAlgorithm  -type f -name '*.cc')
NOISEALGO_OBJECTS = $(NOISEALGO_CXXFILES:.cc=.cc.o)
NOISEALGO_LIBNAME = noisealgo
NOISEALGO_LIBNORNAME = lib$(NOISEALGO_LIBNAME).so

# 规则实现;
all: dirs $(EXE)
	# YEAH,YEAH,YEAH,构建成功.

$(EXE): $(OBJECTS) $(NOISEALGO_LIBNORNAME)
	$(MUTE)$(CXX) -o bin/$(EXE) $(OBJECTS) $(LDFLAGS) \
        -lopencv_core -lopencv_highgui -ldl -lopencv_imgproc\
        -Wl,-rpath=. -Lbin/ -l$(NOISEALGO_LIBNAME) 

$(NOISEALGO_LIBNORNAME): $(NOISEALGO_OBJECTS)
	$(MUTE)$(CXX) -o bin/$(NOISEALGO_LIBNORNAME) $(NOISEALGO_OBJECTS) \
        -shared $(LDFLAGS)


# src/%.cc 会递归搜索 src/ 下所有以 .cc 结尾的文件!
src/NoiseAlgorithm/%.cc.o: src/NoiseAlgorithm/%.cc
	$(MUTE)$(CXX) -o $@ $< -c -fPIC $(CXXFLAGS) $(DEFINES) $(INCLUDESDIR)
src/%.cc.o: src/%.cc
	$(MUTE)$(CXX) -o $@ $< -c $(CXXFLAGS) $(DEFINES) $(INCLUDESDIR)
src/%.c.o: src/%.c
	$(MUTE)$(CC)  -o $@ $< -c $(CFLAGS)   $(DEFINES) $(INCLUDESDIR)


dist: clean $(TARNAME).tar.gz

$(TARNAME).tar.gz: $(DISTDIR)
	$(MUTE)tar czf $(TARNAME).tar.gz $(DISTDIR)
	$(MUTE)rm -rf $(DISTDIR)

$(DISTDIR):
	$(MUTE)mkdir -p $(DISTDIR)
	-$(MUTE)git ls-files | xargs -L 1 dirname | sed -e 's|^|$(DISTDIR)/|' | xargs -L 1 mkdir -p
	-$(MUTE)git ls-files | sed -e 's|\(.*\)|\0 $(DISTDIR)/\0|' | xargs -L 1 cp
	-$(MUTE)rm -f $(DISTDIR)/.gitignore

run: all
	$(MUTE)./bin/$(EXE)

clean:
	$(MUTE)rm $(VTAG) -f $(OBJECTS)
	$(MUTE)rm $(VTAG) -f bin/$(EXE)
	$(MUTE)rm $(VTAG) -f bin/$(NOISEALGO_LIBNORNAME)
	$(MUTE)rm $(VTAG) -f $(NOISEALGO_OBJECTS)

dirs:
	$(MUTE)mkdir -p bin

.PHONY: clean dirs

